package com.itheima.reggie.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Page;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishFlavorMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl implements DishService {

    @Autowired(required = false)
    private DishMapper dishMapper;

    @Autowired(required = false)
    private DishFlavorMapper dishFlavorMapper;

    @Autowired(required = false)
    private CategoryMapper categoryMapper;

    @Autowired(required = false)
    private RedisTemplate redisTemplate;

    @Transactional
    @Override
    public Boolean save(DishDto dishDto) {
        dishDto.setUpdateTime(LocalDateTime.now());
        dishDto.setCreateTime(LocalDateTime.now());
        dishDto.setSort(0);
        dishDto.setStatus(1);

        dishMapper.insert(dishDto);

        List<DishFlavor> dishFlavorList = dishDto.getFlavors().stream().map((dishFlavor -> {
            dishFlavor.setDishId(dishDto.getId());
            dishFlavor.setUpdateTime(LocalDateTime.now());
            dishFlavor.setCreateTime(LocalDateTime.now());
            dishFlavor.setUpdateUser(dishDto.getUpdateUser());
            dishFlavor.setCreateUser(dishDto.getCreateUser());
            return dishFlavor;
        })).collect(Collectors.toList());
        dishFlavorMapper.save(dishFlavorList);

        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);

        return true;
    }

    @Override
    public Page<DishDto> findByPage1(Integer page, Integer pageSize, String name) {
        PageHelper.startPage(page, pageSize);
        List<Dish> dishList = dishMapper.findAll(name);
        PageInfo<Dish> pageInfo = new PageInfo<>(dishList);


        List<DishDto> dishDtoList = pageInfo.getList().stream().map((dish -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
            Category category = categoryMapper.findById(dish.getCategoryId());
            dishDto.setCategoryName(category.getName());
            return dishDto;
        })).collect(Collectors.toList());

        Page<DishDto> pageObj = new Page<>();
        pageObj.setRecords(dishDtoList);
        pageObj.setTotal(pageInfo.getTotal());
        return pageObj;
    }

    @Override
    public Page<DishDto> findByPage2(Integer page, Integer pageSize, String name) {
        PageHelper.startPage(page, pageSize);
        List<DishDto> dishDtoList = dishMapper.findAll2(name);
        PageInfo<DishDto> pageInfo = new PageInfo<>(dishDtoList);

        Page<DishDto> pageObj = new Page<>();
        pageObj.setRecords(dishDtoList);
        pageObj.setTotal(pageInfo.getTotal());
        return pageObj;
    }

    /**
     * 根据id去查询指定的菜品和多个口味
     *
     * @param id
     * @return
     */
    @Override
    public DishDto findById(Long id) {
        return dishMapper.findById(id);
    }


    @Transactional
    @Override
    public R<String> updateById(DishDto dishDto) {
        dishDto.setUpdateTime(LocalDateTime.now());
        dishMapper.updateById(dishDto);
        dishFlavorMapper.deleteById(dishDto.getId());

        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishDto.getId());
            flavor.setCreateTime(LocalDateTime.now());
            flavor.setCreateUser(dishDto.getCreateUser());
            flavor.setUpdateTime(LocalDateTime.now());
            flavor.setUpdateUser(dishDto.getUpdateUser());
        }
        dishFlavorMapper.save(flavors);

        //5. 由于菜品的数据已经发生变化了，那么需要清空缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);

        return R.success("修改成功");
    }

    @Override
    public Boolean updateStatedis(Long[] ids, Integer status) {
        Integer num = dishMapper.updateStatus(ids, status);
        return num > 0;
    }

//    @Override
//    public Boolean updateStateable(Long[] ids) {
//        Integer num = dishMapper.updateStatus1(ids);
//        return num>0;
//    }

    @Override
    public Boolean delete(Long[] ids) {
        Integer num = dishMapper.delete(ids);
        Integer num1 = dishFlavorMapper.delete(ids);

        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);

        return num > 0 & num1 > 0;
    }

    @Override
    public List<Dish> findByCategoryId(Long categoryId) {

        return dishMapper.findByCategoryId(categoryId);
    }

    @Override
    public List<DishDto> findByCategoryId(Long categoryId, Integer status, String name) {

        List<DishDto> dishDtoList = null;
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String key = "dish_" + categoryId + "_" + status;
        dishDtoList = (List<DishDto>) valueOperations.get(key);

        if (dishDtoList == null) {
            List<Dish> dishList = dishMapper.findByCategoryIdAndStatus(categoryId, status, name);
            dishDtoList = dishList.stream().map((dish -> {
                DishDto dishDto = new DishDto();
                BeanUtils.copyProperties(dish, dishDto);

                List<DishFlavor> dishFlavorList = dishFlavorMapper.findByDishId(dishDto.getId());
                dishDto.setFlavors(dishFlavorList);
                //类别信息
                Category category = categoryMapper.findById(dish.getCategoryId());
                dishDto.setCategoryName(category.getName());
                return dishDto;
            })).collect(Collectors.toList());
            valueOperations.set(key, dishDtoList, 60 * 24, TimeUnit.MINUTES);
        }
        return dishDtoList;
    }
}